<template>
  <n-card :bordered="false" size="small">
    <n-grid v-if="auditStatus === 0" cols="1 s:1 m:3 l:3 xl:3 2xl:3" responsive="screen">
      <n-grid-item offset="0 s:0 m:1 l:1 xl:1 2xl:1">
        <n-form :label-width="120" :model="formValue" :rules="rules" ref="formRef">
          <n-form-item label="姓名" path="realName">
            <n-input placeholder="请输入姓名" v-model:value="formValue.realName" />
          </n-form-item>

          <n-form-item label="手机号" path="phone">
            <n-input placeholder="请输入手机号" v-model:value="formValue.phone" />
          </n-form-item>

          <n-form-item label="身份证号" path="idCardNumber">
            <n-input
              v-model:value="formValue.idCardNumber"
              :show-button="false"
              placeholder="请输入身份证号"
            />
          </n-form-item>

          <n-form-item label="身份证（人像面）" path="idCardFront">
            <BasicUpload
              :action="`${apiUrl}/system/oss/upload`"
              :headers="uploadHeaders"
              :max-number="1"
              name="file"
              @upload-change="idCardFrontUploadChange"
              v-model:value="idCardFrontList"
            />
          </n-form-item>

          <n-form-item label="身份证（国徽面）" path="idCardBack">
            <BasicUpload
              :action="`${apiUrl}/system/oss/upload`"
              :headers="uploadHeaders"
              :max-number="1"
              name="file"
              @upload-change="idCardBackUploadChange"
              v-model:value="idCardBackList"
            />
          </n-form-item>

          <n-form-item label="相关证件" path="qualificationCert">
            <BasicUpload
              :action="`${apiUrl}/system/oss/upload`"
              :headers="uploadHeaders"
              :max-number="3"
              name="file"
              @upload-change="qualificationCertUploadChange"
              v-model:value="qualificationCertList"
              helpText="请上传学历证书、教师资格证等相关证件以便后台审核。单个文件不超过20MB，最多只能上传3个文件"
            />
          </n-form-item>

          <n-form-item label="身份" path="identity">
            <n-select
              placeholder="请选择身份"
              :options="identityList"
              v-model:value="formValue.identity"
              disabled
            />
          </n-form-item>

          <n-form-item label="个人简介" path="introduction">
            <n-input
              v-model:value="formValue.introduction"
              type="textarea"
              maxlength="100"
              show-count
              placeholder="个人简介会展示到教师主页"
            />
          </n-form-item>

          <div>
            <n-space>
              <n-button type="primary" :loading="loading" @click="formSubmit">提交申请</n-button>
            </n-space>
          </div>
        </n-form>
      </n-grid-item>
    </n-grid>
    <audit-result v-else :status="auditStatus" :reason="rejectReason" @reapply="handleReapply" />
  </n-card>
</template>
<script lang="ts" setup>
  import { reactive, ref } from 'vue';
  import { useMessage, FormItemRule } from 'naive-ui';
  import { BasicUpload } from '@/components/Upload';
  import { useGlobSetting } from '@/hooks/setting';
  import { useUserStore } from '@/store/modules/user';
  import { applyLecturerApi, getAuditResultApi } from '@/api/course';
  import AuditResult from '@/components/AuditResult.vue';

  const { apiUrl } = useGlobSetting();
  const userStore = useUserStore();
  const token = userStore.getToken;

  const formValue = ref({
    realName: '',
    idCardNumber: '',
    phone: '',
    idCardFront: '',
    idCardBack: '',
    qualificationCert: '',
    identity: 1,
    introduction: '',
  });

  const rules = {
    realName: {
      required: true,
      message: '请输入真实姓名',
      trigger: 'blur',
    },
    idCardNumber: [
      {
        required: true,
        validator(rule: FormItemRule, value: string) {
          const resultMsg = validateCardId(value);
          if (!resultMsg[0]) {
            return true;
          } else {
            return new Error(resultMsg[1]);
          }
        },
        trigger: ['input', 'blur'],
      },
    ],
    idCardFront: {
      required: true,
      message: '请上传身份证（人像面）',
    },
    idCardBack: {
      required: true,
      message: '请上传身份证（国徽面）',
    },
    qualificationCert: {
      required: true,
      message: '请上传相关证件',
    },
    phone: [
      {
        required: true,
        validator(rule: FormItemRule, value: string) {
          if (!/^1[3456789]\d{9}$/.test(value)) {
            return new Error('请输入正确的手机号码');
          } else {
            return true;
          }
        },
        trigger: ['input', 'blur'],
      },
    ],
  };

  const identityList = [
    {
      label: '教师',
      value: 1,
    },
    {
      label: '企业',
      value: 2,
    },
  ];

  const formRef: any = ref(null);
  const message = useMessage();

  const idCardFrontList = ref([]);
  const idCardBackList = ref([]);
  const qualificationCertList = ref([]);
  const uploadHeaders = reactive({
    Authorization: token,
  });

  function idCardFrontUploadChange(list: string[]) {
    formValue.value.idCardFront = list.join(',');
  }
  function idCardBackUploadChange(list: string[]) {
    formValue.value.idCardBack = list.join(',');
  }
  function qualificationCertUploadChange(list: string[]) {
    formValue.value.qualificationCert = list.join(',');
  }

  const loading = ref(false);

  const auditStatus: any = ref(0); // 0=未审核, 1=审核中, 2=审核失败
  const rejectReason: any = ref('身份信息不清晰，请重新提交');

  function formSubmit() {
    formRef.value.validate(async (errors: any) => {
      if (!errors) {
        if (loading.value) return;

        loading.value = true;
        try {
          const res = await applyLecturerApi(formValue.value);

          if (res.code === 200) {
            auditStatus.value = 1;
            message.success('已提交申请');
          }
        } catch (error) {
          console.error('error:', error);
        } finally {
          loading.value = false;
        }
      } else {
        message.error('验证失败，请填写完整信息');
      }
    });
  }

  async function getAuditResult() {
    auditStatus.value = await getAuditResultApi();
  }

  getAuditResult();

  const handleReapply = () => {
    auditStatus.value = 0;
  };

  function resetForm() {
    formRef.value.restoreValidation();
  }

  function validateNull(val: any): boolean {
    if (typeof val == 'boolean') {
      return false;
    }
    if (typeof val == 'number') {
      return false;
    }
    if (val instanceof Array) {
      if (val.length == 0) return true;
    } else if (val instanceof Object) {
      if (JSON.stringify(val) === '{}') return true;
    } else {
      if (val == 'null' || val == null || val == 'undefined' || val == undefined || val == '')
        return true;
      return false;
    }
    return false;
  }

  /**
   * 判断身份证号码
   */
  function validateCardId(code: any) {
    const list = [];
    let result = true;
    let msg = '';
    const city = {
      11: '北京',
      12: '天津',
      13: '河北',
      14: '山西',
      15: '内蒙古',
      21: '辽宁',
      22: '吉林',
      23: '黑龙江 ',
      31: '上海',
      32: '江苏',
      33: '浙江',
      34: '安徽',
      35: '福建',
      36: '江西',
      37: '山东',
      41: '河南',
      42: '湖北 ',
      43: '湖南',
      44: '广东',
      45: '广西',
      46: '海南',
      50: '重庆',
      51: '四川',
      52: '贵州',
      53: '云南',
      54: '西藏 ',
      61: '陕西',
      62: '甘肃',
      63: '青海',
      64: '宁夏',
      65: '新疆',
      71: '台湾',
      81: '香港',
      82: '澳门',
      91: '国外 ',
    };
    if (!validateNull(code)) {
      if (code.length == 18) {
        if (!code || !/(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(code)) {
          msg = '证件号码格式错误';
        } else if (!city[code.substr(0, 2)]) {
          msg = '地址编码错误';
        } else {
          //18位身份证需要验证最后一位校验位
          code = code.split('');
          //∑(ai×Wi)(mod 11)
          //加权因子
          const factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
          //校验位
          const parity = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2, 'x'];
          let sum = 0;
          let ai = 0;
          let wi = 0;
          for (let i = 0; i < 17; i++) {
            ai = code[i];
            wi = factor[i];
            sum += ai * wi;
          }
          if (parity[sum % 11] != code[17]) {
            msg = '证件号码校验位错误';
          } else {
            result = false;
          }
        }
      } else {
        msg = '证件号码长度不为18位';
      }
    } else {
      msg = '证件号码不能为空';
    }
    list.push(result);
    list.push(msg);
    return list;
  }
</script>
<style lang="less" scoped>
  .thing-cell {
    margin: 0 -16px 10px;
    padding: 5px 16px;

    &:hover {
      background: #f3f3f3;
      cursor: pointer;
    }
  }

  .thing-cell-on {
    background: #f0faff;
    color: #2d8cf0;

    ::v-deep(.n-thing-main .n-thing-header .n-thing-header__title) {
      color: #2d8cf0;
    }

    &:hover {
      background: #f0faff;
    }
  }

  ::v-deep(.n-input-number) {
    width: 100%;
  }
</style>
